import * as net from 'net';

export interface ServerOptions {
    host?: string;
    port?: number;
    keepAliveInterval?: number; // 心跳间隔
}

export default class TcpServer {
    private server: net.Server;
    private clients: Map<string, net.Socket>;
    private port: number;
    private host: string;
    private keepAliveInterval: number;

    constructor(options: ServerOptions) {
        this.port = options.port || 8080;
        this.host = options.host || 'localhost';
        this.keepAliveInterval = options.keepAliveInterval || 30000; // 默认心跳间隔为30秒
        this.clients = new Map();

        this.server = net.createServer((socket) => this.handleConnection(socket));
    }

    private handleConnection(socket: net.Socket): void {
        const clientId = `${socket.remoteAddress}:${socket.remotePort}`;
        //console.log(`客户端 ${clientId} 已连接`);
        this.clients.set(clientId, socket);

        socket.on('data', (data) => this.handleData(clientId, data));
        socket.on('end', () => this.handleDisconnect(clientId));
        socket.on('error', (err) => this.handleError(clientId, err));

        this.startHeartbeat(socket);
    }

    protected handleData(clientId: string, data: Buffer): void {
        console.log(`from ${clientId} data: ${data.toString('hex')}`);
        //this.clients.get(clientId)?.write(`server_recv: ${data}`);
    }

    private handleDisconnect(clientId: string): void {
        //console.log(`客户端 ${clientId} 已断开连接`);
        this.clients.delete(clientId);
    }

    private handleError(clientId: string, err: Error): void {
        console.error(`client ${clientId} err: ${err.message}`);
    }

    private startHeartbeat(socket: net.Socket): void {
        const heartbeat = setInterval(() => {
            if (socket.writable) {
                socket.write('心跳包');
            } else {
                clearInterval(heartbeat);
            }
        }, this.keepAliveInterval);

        socket.on('end', () => {
            clearInterval(heartbeat);
        });
    }

    public start(): void {
        this.server.listen(this.port, this.host, () => {
            console.log(`TCP listening ${this.host}:${this.port}`);
        });

        this.server.on('error', (err) => {
            console.error(`server error: ${err.message}`);
        });
    }
}


